﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DBO.Economy;
using DBO;

namespace CommonLibrary
{
    /// <summary>
    /// Abstract resource dictionnay that implements proxy methods above data transactions
    /// and a caching level for keeping already loaded data. Index with string keys.
    /// </summary>
    /// <typeparam name="T">The type of data contained?</typeparam>
    public abstract class ResourceDictionnary<T> : IResourceDictionnary
    {
        /// <summary>
        /// Gets a resource.
        /// </summary>
        /// <param name="Key"></param>
        /// <returns></returns>
        public T Get(string Key)
        {
            if (IsCached(Key))
                return InnerGet(Key);

            return Cache(Key, SourceGet(Key));
        }

        /// <summary>
        /// Veryfies of a resource is already in cache.
        /// </summary>
        /// <param name="Key"></param>
        /// <returns></returns>
        public bool IsCached(string Key)
        {
            return _content.ContainsKey(Key);
        }

        /// <summary>
        /// Puts a resource in cache.
        /// </summary>
        /// <param name="Key"></param>
        /// <param name="Object"></param>
        /// <returns>The object being added.</returns>
        public T Cache(string Key, T Object)
        {
            _content.Add(Key, Object);
            return Object;
        }

        public Type ContentTypeGet()
        {
            return typeof(T);
        }

        public object RawGet(string Key)
        {
            return Get(Key);
        }

        public void InvalidateKey(string Key)
        {
            _content.Remove(Key);
        }

        public void InvalidateAll()
        {
            _content.Clear();
        }

        #region Protected

        /// <summary>
        /// Gets a resource from the data source.
        /// </summary>
        /// <param name="Key"></param>
        /// <returns></returns>
        protected abstract T SourceGet(string Key);

        /// <summary>
        /// Gets a data from inner cache.
        /// </summary>
        /// <param name="Key"></param>
        /// <returns></returns>
        protected T InnerGet(string Key)
        {
            return _content[Key];
        }

        protected Dictionary<string, T> _content = new Dictionary<string, T>();
        #endregion

    }
}
